<template>
  <div class="crop">
    <el-dialog
      :model-value="isCropperVisible"
      title="上传Logo"
      width="600px"
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <div class="image-container">
        <!-- 尺寸要求提示 -->
        <div class="size-warning">
          <el-alert
            type="warning"
            title="logo尺寸不小于280*90"
            show-icon
            :closable="false"
          />
        </div>

        <!-- 裁剪区域 -->
        <vue-cropper
          ref="cropper"
          style="height: 150px"
          :img="imageSrc"
          :outputSize="option.outputSize"
          :canMove="option.canMove"
          :fixedBox="option.fixedBox"
          :enlarge="option.enlarge"
          :autoCrop="option.autoCrop"
          :autoCropWidth="option.autoCropWidth"
          :original="option.original"
          :fixed-number="option.fixedNumber"
          :autoCropHeight="option.autoCropHeight"
          :mode="option.mode"
          v-if="imageSrc"
        />
        <el-upload
          class="upload-demo"
          ref="uploadRef"
          :limit="1"
          accept=".jpg,.png"
          v-else
          :headers="upload.headers"
          :http-request="customUploadRequest"
          :show-file-list="false"
        >
          <img v-if="imageSrc" :src="imageSrc" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon">
            <Plus />
          </el-icon>
        </el-upload>
        <!-- 操作按钮 -->
        <div class="cropper-buttons">
          <el-button @click="resetCropper">重新上传</el-button>
          <el-button @click="closeDialog">取消</el-button>
          <el-button type="primary" @click="getCroppedImage">确定</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue';
import { VueCropper } from 'vue-cropper';
import 'vue-cropper/dist/index.css';
import { getToken } from '@/utils/auth';
import { toBase64 } from '@/utils';
import { ElMessage } from 'element-plus';
import { uploadFile } from '@/api/serviceCenter';

const emit = defineEmits(['update:isCropperVisible', 'crop']);
const props = defineProps({
  // 接收从父组件传来的图片地址
  imageUrl: {
    type: String,
    required: true,
  },
  // 控制对话框的显示与隐藏
  isCropperVisible: {
    type: Boolean,
    required: true,
  },
  // 控制裁剪比例
  aspectRatio: {
    type: Number,
    default: 187 / 60, // 默认为 187:60
  },
});
// 裁剪组件配置
const option = reactive({
  img: '', //裁剪图片的地址
  outputSize: 1, //裁剪生成图片的质量(可选0.1 - 1)
  outputType: 'png', //裁剪生成图片的格式（jpeg || png || webp）
  info: true, //图片大小信息
  canScale: true, //图片是否允许滚轮缩放
  autoCrop: true, //是否默认生成截图框
  autoCropWidth: 280, //默认生成截图框宽度
  autoCropHeight: 90, //默认生成截图框高度
  fixed: true, //是否开启截图框宽高固定比例
  fixedNumber: [1, 1], //截图框的宽高比例
  full: false, //false按原比例裁切图片，不失真
  fixedBox: true, //固定截图框大小，不允许改变
  canMove: false, //上传图片是否可以移动
  canMoveBox: true, //截图框能否拖动
  original: false, //上传图片按照原始比例渲染
  centerBox: false, //截图框是否被限制在图片里面
  height: true, //是否按照设备的dpr 输出等比例图片
  infoTrue: false, //true为展示真实输出图片宽高，false展示看到的截图框宽高
  maxImgSize: 3000, //限制图片最大宽度和高度
  enlarge: 1, //图片根据截图框输出比例倍数
  mode: '230px 150px', //图片默认渲染方式
});
// 上传参数
const upload = reactive({
  // 上传二维码弹窗变量
  open: false,
  // 弹出层标题
  title: '上传图片',
  // 是否更新已经存在的用户数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: { Token: getToken() },
  // 上传的地址
  url: '/dev-api/api/index/imageUpload',
  imgurl: '',
  // 是否禁用上传
  disabled: true,
});
const imageSrc = ref(props.imageUrl); // 图片数据
const cropper = ref(null);
// 自定义上传请求的逻辑
const customUploadRequest = async ({
  file,
  onSuccess,
  onError,
  onProgress,
}) => {
  // 文件大小限制为 5MB
  const maxFileSize = 5 * 1024 * 1024; // 5MB

  // 判断文件大小是否超过 5MB
  if (file.size > maxFileSize) {
    ElMessage({
      message: '文件大小不能超过 5MB',
      type: 'error',
    });
    return; // 阻止上传
  }
  // 调用封装的 uploadFile 函数来处理上传逻辑
  uploadFile(
    file,
    upload.url, // 上传的 URL
    upload.headers, // 自定义请求头
    (progressEvent) => {
      // 进度回调
      const progress = (progressEvent.loaded / progressEvent.total) * 100;
      onProgress({ percent: progress }); // 进度回调
    },
    (response) => {
      onSuccess(response); // 上传成功的回调
      upload.imgurl = response.data.url; // 假设返回的图片 URL 存储在 response.data.url
      upload.disabled = false; // 上传成功后允许再次上传
      toBase64(upload.imgurl, 0.8)
        .then((base64) => {
          imageSrc.value = base64;
        })
        .catch(() => {});
    },
    (error) => {
      onError(error); // 上传失败的回调
    }
  );
  upload.disabled = false; // 重置上传状态
};

// 裁剪图片逻辑
const getCroppedImage = () => {
  cropper.value.getCropData((data) => {
    imageSrc.value = data;
  });
  emit('crop', imageSrc.value); // 通知父组件裁剪后的结果
  emit('update:isCropperVisible', false);
};

// 重置裁剪区域
const resetCropper = () => {
  imageSrc.value = null; // 清除图片
};

const closeDialog = () => {
  emit('update:isCropperVisible', false);
};
</script>

<style scoped lang="scss">
.image-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.size-warning {
  width: 100%;
  text-align: left;
}

.cropper-buttons {
  margin-top: 10px;
  display: flex;
  justify-content: space-between;
}
</style>
<style lang="scss">
.crop {
  .el-dialog__body {
    padding-top: 0 !important;
  }

  .el-alert--warning.is-light {
    background: none;
  }

  .el-alert__title {
    color: #787f8b;
  }

  .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    width: 153px;
    height: 153px;

    .el-icon {
      font-size: 28px;
      color: #8c939d;
    }
  }
}
</style>
